﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Galoap
{
    /// <summary>
    /// The Question abstract superclass
    /// </summary>
    partial class Question
    {
        /// <summary>
        /// Dynamic text of the question
        /// </summary>
        public QuestionText TextBuilder { get; set; }
        public string Text { get; set; }

        /// <summary>
        /// The answer in which we want to ask a confirm 
        /// </summary>
        public string MyReply{ get; set; }

        /// <summary>
        /// the number of answer that we require before asking a confirm
        /// </summary>
        protected int threshold { get; set; }

        /// <summary>
        /// the probably of asking a confirm (if threshold is exceeded)
        /// </summary>
        protected float probablyOfRequestOfConfirm { get; set; }

        /// <summary>
        /// void constructor
        /// </summary>
        public Question()
            : base()
        {
            // sdefault definition opf confirm
            threshold = 1;
            probablyOfRequestOfConfirm = 0.6f;
        }


        /// <summary>
        /// validate method which test if the format of the answer is correct for this question. 
        /// </summary>
        /// <param name="reply">the representation string of the answer</param>
        /// <returns>true if the param is valid, false otherwise</returns>
        virtual public bool Validate(string reply)
        {
            // default validate, it takes all the answers
            return true;
        }

        /// <summary>
        /// init method to inizialize Question and other features
        /// </summary>
        public virtual void Initialize()
        {
            try
            {
                // check if there is a threshold of answer to make confirm questions
                if (threshold > 0)
                {
                    Random r = new Random();
                    List<StringAnswer> sal = GetAnswersWithCountGreaterThan<StringAnswer>(-10);//  GetAnswersOrderedByFrequency<StringAnswer>();

                    int index = r.Next(sal.Count - 1);
                    // if answers are more than threshold it tests for probably to make a confirm question
                    if (sal.Count >= threshold && r.Next(100) < probablyOfRequestOfConfirm * 100)
                    {
                        StringAnswer a = sal.ElementAt(index);
                        Text = TextBuilder.GetConfirmQuestionText(a.Data);
                        // set MyReply which it requests a confirm
                        MyReply = a.Data;
                    }
                    else
                    {
                        Text = TextBuilder.GetQuestionText();
                        MyReply = "";
                    }
                }
                else
                {
                    Text = TextBuilder.GetQuestionText();
                    MyReply = "";
                }
            }
            catch (InvalidOperationException)
            {
                Text = TextBuilder.GetQuestionText();
                MyReply = "";
            }
        }

        /// <summary>
        /// method which saves in database an answer given to this question
        /// </summary>
        /// <typeparam name="T">the type of the answer to save</typeparam>
        /// <param name="gs">the gamesession which an user is responding</param>
        /// <param name="answer">the given answer</param>
        /// <returns>the answer saved on database</returns>
        public virtual T SaveAnswer<T>(GameSession gs, string answer) where T : Answer, new()
        {
            if (answer.Length > 2)
            {
                // it checks if it's a confirm answer
                if (answer.Substring(0, 2).Equals("n-"))
                    // no
                    return Galoap.Answer.CreateAnswer<T>(this, gs, answer.Substring(2, answer.Length - 2), false);
                else if (answer.Substring(0, 2).Equals("y-"))
                    // yes
                    return Galoap.Answer.CreateAnswer<T>(this, gs, answer.Substring(2, answer.Length - 2));
            }
            return Galoap.Answer.CreateAnswer<T>(this, gs, answer);
        }

        /// <summary>
        /// method which return the number of valid answers given to this question
        /// </summary>
        /// <returns>the number of valid answers</returns>
        public virtual int GetMostFrequentValidAnswerCount()
        {
            return GetMostFrequentAnswerCount<Answer>();
        }

    }
}
